#pragma once

#include "FiringEvent.h"

using namespace System;
using namespace System::Collections::Generic;

namespace SpikingNeuronLib
{
	// Temporary storage for match aggregation
	public value struct MatchIndex
	{
		property int TimeIndex;									// time index at which a match occurs
		property int MatchCount;								// the number of matching firing events in the template
		property array<bool>^ MatchedEvents;					// the events that matched at this time index

		MatchIndex(int timeIndex, int matchCount, array<bool>^ matchedEvents)
		{
			TimeIndex = timeIndex; MatchCount = matchCount; MatchedEvents = matchedEvents;
		}
	};

	// For in-memory scans, the Tag is a state file identifier and the Index is a firing data index (secs) for data generated from that state
	// For file-scans, the Tag can be null and the Index is the index of the file being scanned
	public value struct MatchResult
	{
		property String^ Tag;									// normally stores a file identifier such as the sequential time index for that file
		property int TemplateID;								// the index into the TemplateList
		property int UniqueID;									// a unique ID (see Pattern UniqueID)
		property int Index;										// the index of the file or the in-memory firing data that matched (assuming each file is one second of data)
		property int Offset;									// the offset that the match occurred within the segment (in msec)
		property int MatchCount;								// number of events that matched on this template
		property String^ MatchPattern;							// a bit string showing which firing events matched
		property array<FiringEvent>^ CoincidentFiringEvents;	// the firing events that matched

		MatchResult(String^ tag, int templateID, int uniqueID, int index, int offset, int matchCount, String^ matchPattern, array<FiringEvent>^ coincidentFiringEvents)
		{
			Tag = tag;
			TemplateID = templateID;
			UniqueID = uniqueID;
			Index = index;
			Offset = offset;
			MatchCount = matchCount;
			MatchPattern = matchPattern;
			CoincidentFiringEvents = coincidentFiringEvents;
		}
	};

	public value struct MatchRaster
	{
	public:
		property array<array<int>^>^ DataMatch;
		property array<array<int>^>^ TemplateMatch;

		MatchRaster(array<array<int>^>^ dataMatch, array<array<int>^>^ templateMatch) { this->DataMatch = dataMatch; this->TemplateMatch = templateMatch; }
	};

	public ref struct CacheData
	{
	public:
		property List<FiringEvent>^ FiringData;
		long LastAccess;

		CacheData(List<FiringEvent>^ firings, long lastAccess) { FiringData = firings; LastAccess = lastAccess; }
	};
}
